package com.sxbbc.common.core.wx;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sxbbc.common.basics.files.RestUploadFileInfo;
import com.sxbbc.common.basics.files.UploadUtils;
import com.sxbbc.common.basics.https.HttpUtil;
import com.sxbbc.common.basics.wx.DecryptUtil;
import com.sxbbc.common.basics.wx.client.WxClient;
import com.sxbbc.common.basics.wx.client.WxProgramClient;
import com.sxbbc.common.core.entity.jz.InfoWx;
import com.sxbbc.common.core.utils.RedisUtils;

/**
 * 微信公用层
 *
 * @author Arno
 */
public class WxUtils {

    public static WxUtils wxUtils = null;
    private static InfoWx infoWx = null;

    public static WxUtils getInstance() {
        if (wxUtils == null) {
            synchronized (WxUtils.class) {
                if (wxUtils == null) {
                    wxUtils = new WxUtils();
                }
            }
        }
        infoWx = RedisUtils.getInstance().getWxInfo();
        return wxUtils;
    }

    /**
     * 根据授权code 获取微信用户id
     *
     * @param code
     * @return
     */
    public String getOpenIDByCode(String code) {
        String param = "appid=" + infoWx.getAppId() + "&secret=" + infoWx.getAppsecretKey() + "&code=" + code + "&grant_type=authorization_code";
        //开始获取openid
        String result = HttpUtil.getInstance().post("https://api.weixin.qq.com/sns/oauth2/access_token", param);
        JSONObject jsonObject = JSONObject.parseObject(result);
        String openid = jsonObject.getString("openid");
        return openid;
    }

    /**
     * 获取微信token
     *
     * @return
     */
    public String getToken() {
        //1.第一部先获取到access_token
        String param = "grant_type=client_credential&appid=" + infoWx.getAppId() + "&secret=" + infoWx.getAppsecretKey();
        String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
        String resultToken = HttpUtil.getInstance().post(accessTokenUrl, param);
        JSONObject tokenJson = JSONObject.parseObject(resultToken);
        String access_token = tokenJson.getString("access_token");
        return access_token;
    }

    /**
     * 获取微信网页授权token
     *
     * @return
     */
    public Map<String, String> getWebToken(String code) {
        //1.第一部先获取到access_token
        String param = "grant_type=authorization_code&appid=" + infoWx.getAppId() + "&secret=" + infoWx.getAppsecretKey() + "&code=" + code;
        String accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
        String resultToken = HttpUtil.getInstance().post(accessTokenUrl, param);
        JSONObject tokenJson = JSONObject.parseObject(resultToken);
        String access_token = tokenJson.getString("access_token");
        String openid = tokenJson.getString("openid");
        String unionid = tokenJson.getString("unionid");
        Map<String, String> map = new HashMap<String, String>();
        map.put("access_token", access_token);
        map.put("openid", openid);
        map.put("unionid", unionid);
        return map;
    }

    /**
     * 获取微信JSSDK的ticket
     *
     * @author Benson
     */
    public String getJSSDKTicket(String token) {
        String param = "access_token=" + token + "&type=jsapi";
        String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        String resultToken = HttpUtil.getInstance().post(accessTokenUrl, param);
        JSONObject tokenJson = JSONObject.parseObject(resultToken);
        String ticket = tokenJson.getString("ticket");
        return ticket;
    }

    /**
     * 获取微信用户对象
     *
     * @param token
     * @param openid
     * @return
     */
    public WxClient getWXClient(String token, String openid) {
        //2 根据access_token获取用户信息
        String result = HttpUtil.getInstance().
                post("https://api.weixin.qq.com/cgi-bin/user/info", "access_token=" + token + "&openid=" + openid + "&lang=zh_CN");
        WxClient client = JSON.parseObject(result, WxClient.class);
        return client;
    }

    /**
     * 获取微信网页授权用户对象
     *
     * @param token
     * @param openid
     * @return
     */
    public WxClient getWebWXClient(String token, String openid) {
        //2 根据access_token获取用户信息
        String result = HttpUtil.getInstance().
                post("https://api.weixin.qq.com/sns/userinfo", "access_token=" + token + "&openid=" + openid + "&lang=zh_CN");
        System.out.println(result);
        WxClient client = JSON.parseObject(result, WxClient.class);
        return client;
    }

    /**
     * 生成微信菜单
     *
     * @param menus 菜单字符串
     * @return
     */
    public boolean generateMenu(String menus) {
        //2 根据access_token获取用户信息
        String token = RedisUtils.getInstance().getWxToken();
        String result = HttpUtil.getInstance().post("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + token, menus);
        JSONObject object = JSONObject.parseObject(result);
        if ("ok".equals(object.getString("errmsg"))) {
            return true;
        }
        return false;
    }

    /**
     * 删除微信菜单
     *
     * @return
     */
    public boolean deleteMenu() {
        //2 根据access_token获取用户信息
        String token = RedisUtils.getInstance().getWxToken();
        String result = HttpUtil.getInstance().post("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=" + token, "");
        JSONObject object = JSONObject.parseObject(result);
        if ("ok".equals(object.getString("errmsg"))) {
            return true;
        }
        return false;
    }

    /**
     * 生产微信二维码
     *
     * @param params 参数
     * @return 返回二维码解析 URL、
     */
    public String createQR(String params) {
        String token = RedisUtils.getInstance().getWxToken();
        //{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "123"}}}
        JSONObject obj = new JSONObject();
        obj.put("action_name", "QR_LIMIT_STR_SCENE");//设置永久二维码
        JSONObject paramsObj = new JSONObject();
        JSONObject pobj = new JSONObject();
        pobj.put("scene_str", params);
        paramsObj.put("scene", pobj);
        obj.put("action_info", paramsObj);
        String p = obj.toJSONString();
        //2 根据access_token获取用户信息
        String result = HttpUtil.getInstance().post("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + token, p);
        JSONObject object = JSONObject.parseObject(result);
        String url = object.getString("url");
        return url;
    }

    /**
     * 微信主动推送消息给用户
     */
    public void wxPustText(String openid, String content) {
        String token = RedisUtils.getInstance().getWxToken();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", openid);
        jsonObject.put("msgtype", "text");
        JSONObject conobj = new JSONObject();
        conobj.put("content", content);
        jsonObject.put("text", conobj);
        String p = jsonObject.toJSONString();
        System.out.println(p);
        //2 根据access_token获取用户信息
        HttpUtil.getInstance().post("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + token, p);
    }

    /**
     * 小程序根据code获取微sessionkey
     *
     * @param code
     * @return
     */
    public String getSessionkey(String code) {
        //2 根据access_token获取用户信息
        if (infoWx != null) {
            String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + infoWx.getProgramAppid() + "&secret=" + infoWx.getProgramSecret() + "&js_code=" + code + "&grant_type=authorization_code";
            String result = HttpUtil.getInstance().post(url, "");
            JSONObject object = JSONObject.parseObject(result);
            String sessionkey = object.getString("session_key");
            return sessionkey;
        } else {
            return "";
        }
    }

    /**
     * 获取小程序用户对象
     *
     * @param sessionkey
     * @param encryptedData
     * @param iv
     * @return
     */
    public WxProgramClient getProgram(String sessionkey, String encryptedData, String iv) {
        String result = DecryptUtil.getStr(encryptedData, sessionkey, iv);
        WxProgramClient client = JSON.parseObject(result, WxProgramClient.class);
        return client;
    }

    /**
     * 获取小程序token
     *
     * @return
     */
    public String getProgramToken() {
        //1.第一部先获取到access_token
        String param = "grant_type=client_credential&appid=" + infoWx.getProgramAppid() + "&secret=" + infoWx.getProgramSecret();
        String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
        String resultToken = HttpUtil.getInstance().post(accessTokenUrl, param);
        JSONObject tokenJson = JSONObject.parseObject(resultToken);
        String access_token = tokenJson.getString("access_token");
        return access_token;
    }

    /**
     * 生产微信小程序二维码
     *
     * @param params 参数
     * @return 返回二维码解析 URL、
     * @path 路径
     */
    public String createProgramQR(String path, String params) {
        String qr = "";
        try {
            String token = RedisUtils.getInstance().getWxProgramToken();
            JSONObject obj = new JSONObject();
            //设置永久二维码
            obj.put("path", path);
            //设置永久二维码
            obj.put("scene", params);
            //2 根据access_token获取用户信息
            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token;
            MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
            HttpEntity<JSONObject> requestEntity = new HttpEntity<>(obj, headers);
            RestTemplate rest = new RestTemplate();
            ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
            InputStream inputStream = null;
            byte[] result = entity.getBody();
            inputStream = new ByteArrayInputStream(result);

            RestUploadFileInfo fileInfo = UploadUtils.getInstance().uploadFile(inputStream, params + ".jpg");
            if (fileInfo.isStatus()) {
                qr = fileInfo.getData();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return qr;
    }

    public static void main(String[] args) {

//		String appid = "wxda364bc6a3f35350";
//		String secret = "c83a027b17f532d8f2b908fc96542e2b";
//		String param="grant_type=client_credential&appid="+appid+"&secret="+secret;
//		String accessTokenUrl="https://api.weixin.qq.com/cgi-bin/token";
//		String resultToken=HttpUtil.getInstance().post(accessTokenUrl, param);
//		JSONObject tokenJson=JSONObject.parseObject(resultToken);
//		String access_token=tokenJson.getString("access_token");
//		System.out.println(access_token);

        String path = "pages/share/referrer";
        String params = "inviteCode=1";

        String qr = "";
        try {
            String token = "23_hNOoGxoYNne30xaV19cbqNnqJIXD2sDPC-QHeY7fbjL7kNEL5LT-5YClbc26OJ9If2kdQZ8UE_ODbmQEEiA-3V6fSTe8ZypkGqEtKUE0tv7nsZUjgtXdY2uUuqpX7GN-gGVcORjDj0Mty5aiBTBcACARJR";
            JSONObject obj = new JSONObject();
            obj.put("path", path);//设置永久二维码
            obj.put("scene", params);//设置永久二维码
            //2 根据access_token获取用户信息
            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token;
            MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
            HttpEntity<JSONObject> requestEntity = new HttpEntity<>(obj, headers);
            RestTemplate rest = new RestTemplate();
            ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
            InputStream inputStream = null;
            byte[] result = entity.getBody();
            inputStream = new ByteArrayInputStream(result);

            RestUploadFileInfo fileInfo = UploadUtils.getInstance().uploadFile(inputStream, params + ".jpg");
            if (fileInfo.isStatus()) {
                qr = fileInfo.getData();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(qr);

    }
}
